package com.blyat.xsoft.gateway.ribbon.loadbalancer.server;

import com.google.common.eventbus.Subscribe;
import com.netflix.client.config.IClientConfig;
import com.netflix.client.config.IClientConfigKey;
import com.netflix.loadbalancer.AbstractServerList;
import org.springframework.util.Assert;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * @Auther: syh
 * @Date: 2020/8/24
 * @Description:
 */
public class DynamicServerList<T extends XSoftServer> extends AbstractServerList<T> {
    private ServerLoader<T> serverLoader;
    private IClientConfig clientConfig;

    public void setServerLoader(@NotNull ServerLoader serverLoader) {
        this.serverLoader = serverLoader;
    }

    @Override
    public List<T> getInitialListOfServers() {
        return getUpdatedListOfServers();
    }

    /**
     * 该方法30秒被调用一次，可做可用服务的实时更新
     *
     * @return
     */
    @Override
    public List<T> getUpdatedListOfServers() {
        Assert.notNull(serverLoader, "serverLoader must be specify.");
        try {
            // loadServers by clientName;
            return serverLoader.getServerByClient(this.clientConfig.getClientName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 30秒刷新一次服务实例，最差情况下会出现30秒误差时间。
     * 比如getUpdatedListOfServers刚被定时调用过，服务就被修改，那么要等下一个30秒以后服务信息才会被刷新。
     * <p>
     * 可以添加修改服务实例更新的filter，配合事件驱动实时修改可用服务。
     */
    @Subscribe
    public void updateServers() {
        this.clientConfig.set(IClientConfigKey.Keys.ListOfServers, "");
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        this.clientConfig = clientConfig;
    }
}
